package com.pubinfo.passbook.common.entity;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.pubinfo.passbook.common.model.bo.witeoff.WiteoffBase;
import com.pubinfo.passbook.common.model.dto.open.WiteoffData;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.BeanUtils;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

/**
 * 报账单表
 *
 * @TableName t_witeoff_instance
 */
@TableName(value = "t_witeoff_instance")
@Data
@NoArgsConstructor
@ApiModel(value = "TWiteoffInstance", description = "报账单表")
public class TWiteoffInstance implements Serializable {
  /**
   *
   */
  @TableId
  private String id;
  
  @ApiModelProperty(value = "调用方系统编码 必须")
  public String systemCode;
  @ApiModelProperty("外围系统主单Id")
  private String otherSystemMainId;
  
  /**
   * 报账系统 报账单号
   */
  @ApiModelProperty("报账系统 报账单号")
  private String witeoffInstanceCode;
  
  /**
   * 报账人账号
   */
  @ApiModelProperty("报账人账号")
  private String account;
  
  /**
   * 报账人姓名
   */
  @ApiModelProperty("报账人姓名")
  private String fillInName;
  
  /**
   * 报账组织编码
   */
  @ApiModelProperty("报账组织编码")
  private String fillInOrgCode;
  
  /**
   * 公司代码
   */
  @ApiModelProperty("公司代码")
  private String sapCompayCode;
  
  /**
   * 经济事项编码
   */
  @ApiModelProperty("经济事项编码")
  private String economicItemCode;
  
  /**
   * 经济事项名称
   */
  @ApiModelProperty("经济事项名称")
  private String economicItemName;
  
  /**
   * 收支方式 选项：1 已支付-委托银行划扣-本地划扣 2 已支付-本地已主动支付 3 已支付-委托银行划扣-集中划扣 4 涉及付款-银行支付-集中支付 5 涉及付款-商业汇票-汇票支付 6 涉及收款-本地收款 7 涉及收款-集中收款 8 不涉及收付
   */
  @ApiModelProperty("收支方式 选项：1 已支付-委托银行划扣-本地划扣 2 已支付-本地已主动支付 3 已支付-委托银行划扣-集中划扣 4 涉及付款-银行支付-集中支付 5 涉及付款-商业汇票-汇票支付 6 涉及收款-本地收款 7 涉及收款-集中收款 8 不涉及收付")
  private String paymentType;
  
  /**
   * 费用发生日	必须	格式为：YYYY-MM-DD
   */
  @ApiModelProperty("费用发生日  必须\t格式为：YYYY-MM-DD")
  @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
  private Date happenDate;
  
  /**
   * 报账期间	 	格式必为：YYYY-MM
   */
  @ApiModelProperty("报账期间   格式必为：YYYY-MM")
  private String budgetSet;
  
  /**
   * 业务类型	必须	选项：0-列账，1-付款,2-列并付
   */
  @ApiModelProperty("业务类型  必须  选项：0-列账，1-付款,2-列并付")
  private String bizType;
  
  /**
   * 会计科目编码	非必须	可从SAP获取基础数据
   */
  @ApiModelProperty("会计科目编码\t非必须\t可从SAP获取基础数据")
  private String accountCode;
  
  /**
   * 会计科目名称	非必须
   */
  @ApiModelProperty("会计科目名称\t非必须")
  private String accountName;
  
  /**
   * 科目类型	非必须	选输(1-总账、2-供应商、3-客户),有科目时必须
   */
  @ApiModelProperty("科目类型\t非必须\t选输(1-总账、2-供应商、3-客户),有科目时必须")
  private String accountType;
  
  /**
   * 是否员工代垫	必须	如不涉及银行支付，请提供空值, 选项：0-否，1-是
   */
  @ApiModelProperty("是否员工代垫\t必须\t如不涉及银行支付，请提供空值, 选项：0-否，1-是")
  private Byte isStaffPayment;
  
  /**
   * 业务编码类型	非必须	选项 1-合同  3-采购订单号  5-框架汇总单号 如果为空，而且合同编码/业务编码字段又存在，则默认为1-合同
   */
  @ApiModelProperty("业务编码类型\t非必须\t选项 1-合同  3-采购订单号  5-框架汇总单号 如果为空，而且合同编码/业务编码字段又存在，则默认为1-合同")
  private Byte bizCodeType;
  
  /**
   * 合同编码/业务编码
   */
  @ApiModelProperty("合同编码/业务编码")
  private String contractNo;
  
  /**
   * 合同名称/业务名称
   */
  @ApiModelProperty("合同名称/业务名称")
  private String contractName;
  
  /**
   * 报账金额	必须	子单总金额必需等于报账金额
   */
  @ApiModelProperty("报账金额\t必须\t子单总金额必需等于报账金额")
  private BigDecimal sum;
  
  /**
   * 说明
   */
  @ApiModelProperty("说明")
  private String desc_;
  
  /**
   * 票据类型	非必须	当集成业务涉及增值税时，必须。 选项：1-增值税专用发票，2-增值税普通发票，3-营业税发票，4-货物运输专用发票，5-                                机动车销售统一发票，6-海关进口增值税专用缴款书，8-普通收据，9无发票，10-国外                                    发票（国外账单），11-代扣代缴税收通用缴款书，12-电子发票-普票，13-增值                                      税专用发票（免税高新企业），14-通行费电子发票，15-通用发票
   */
  @ApiModelProperty("票据类型\t非必须\t当集成业务涉及增值税时，必须。 选项：1-增值税专用发票，2-增值税普通发票，3-营业税发票，4-货物运输专用发票，5-")
  private Byte invoiceType;
  
  /**
   * 是否需要手工扫描	必须	0-否，1-是
   */
  @ApiModelProperty("是否需要手工扫描\t必须\t0-否，1-是")
  private Byte isNeedImage;
  
  /**
   * 是否预付款 非必须	是否预付款,1:是,0:否
   */
  @ApiModelProperty("是否预付款 非必须\t是否预付款,1:是,0:否")
  private String isPrePay;
  
  /**
   * 外围系统查看业务数据URL
   */
  @ApiModelProperty("外围系统查看业务数据URL")
  private String showDataUrl;
  /**
   * 精确到2位小数点	进项税金额
   */
  @ApiModelProperty("精确到2位小数点\t进项税金额")
  private BigDecimal inputTaxSum;
  @ApiModelProperty("报账人手机号")
  private String phone;
  @ApiModelProperty("报账人身份证号")
  private String idNo;
  /**
   * 精确到2位小数点	实收金额
   */
  @ApiModelProperty("精确到2位小数点\t实收金额")
  private BigDecimal actualTokenSum;
  
  /**
   * 是否调用预算	非必须	0:不调用 1：调用 空：通过经济事项+省级编码+外围系统       标识到配置表进行查找
   */
  @ApiModelProperty("是否调用预算  非必须  0:不调用 1：调用 空：通过经济事项+省级编码+外围系统  标识到配置表进行查找")
  private Byte isBudget;
  
  /**
   * 2	是否存在实物赠送	营改增业务必填	是否存在实物赠送 1：是0:否 实物  赠送金额	real_gift_sum	BigDecimal	精确到2位小数点	实物赠送金额	营改增业务必填	实物赠送金额
   */
  @ApiModelProperty("是否存在实物赠送\t营改增业务必填\t是否存在实物赠送 1：是0:否 实物  赠送金额\treal_gift_sum\tBigDecimal\t精确到2位小数点\t实物赠送金额\t营改增业务必填\t实物赠送金额")
  private Byte isRealGift;
  /**
   * 精确到2位小数点	实付金额
   */
  @ApiModelProperty("精确到2位小数点\t实付金额")
  private BigDecimal actualPaidSum;
  /**
   * 精确到2位小数点	实物赠送税额	营改增业务必填
   */
  @ApiModelProperty("精确到2位小数点\t实物赠送税额\t营改增业务必填")
  private BigDecimal realGiftTaxSum;
  
  /**
   * 精确到2位小数点	实物赠送金额	营改增业务必填
   */
  @ApiModelProperty("精确到2位小数点\t实物赠送金额\t营改增业务必填")
  private BigDecimal realGiftSum;
  
  /**
   * 业务发生时间点标志	营改增业务必填	业务发生时间                                                点标志(1-[营改增日期]前，2-[营改增日期]后)
   */
  @ApiModelProperty("业务发生时间点标志\t营改增业务必填\t业务发生时间  ")
  private Byte businessHappenTimeFlag;
  
  /**
   * 2	纳税属性	非必须	1-属地纳税、2-汇总纳税、3-汇总传统，根据经济事项         配置的数据默认推导
   */
  @ApiModelProperty("纳税属性\t非必须\t1-属地纳税、2-汇总纳税、3-汇总传统，根据经济事项         配置的数据默认推导")
  private Byte payTaxAttribute;
  
  /**
   * 业务场景（挑对模式）	非必须	业务场景（挑对模式）
   */
  @ApiModelProperty("业务场景（挑对模式）\t非必须\t业务场景（挑对模式）")
  private Byte pickingMode;
  
  /**
   * 默认CNY 枚举项：  CNY HKD  JPY USD
   */
  @ApiModelProperty("默认CNY 枚举项：  CNY HKD  JPY USD")
  private String currency;
  
  /**
   * 特殊总账标识
   */
  @ApiModelProperty("特殊总账标识")
  private String specialTag;
  
  /**
   * 备选统驭科目编码
   */
  @ApiModelProperty("备选统驭科目编码")
  private String preAccountCode;
  
  /**
   * 备选统驭科目名称
   */
  @ApiModelProperty("备选统驭科目名称")
  private String preAccountName;
  
  /**
   * 是否付款	非必须	0-否，1-是，2-其他
   */
  @ApiModelProperty("是否付款\t非必须\t0-否，1-是，2-其他")
  private Byte isPayment;
  
  /**
   * 是否加急	非必须	0-否，1-是
   */
  @ApiModelProperty("是否加急\t非必须\t0-否，1-是")
  private Byte isEmergency;
  
  /**
   * 是否涉及进项税转出	非必须	0-否，1-是
   */
  @ApiModelProperty("是否涉及进项税转出\t非必须\t0-否，1-是")
  private Byte isInputTax;
  
  /**
   * 进项税转出税额	非必须	是否进项税转出为是时必输 精确到2位小数点
   */
  @ApiModelProperty("进项税转出税额\t非必须\t是否进项税转出为是时必输 精确到2位小数点")
  private BigDecimal inputTaxTurnSum;
  
  /**
   * 进项税转出业务类型	非必须	1：免税项目  2：非免税项目
   */
  @ApiModelProperty("进项税转出业务类型\t非必须\t1：免税项目  2：非免税项目")
  private Byte inputTaxTurnBizType;
  
  /**
   * 往来类型编码
   */
  @ApiModelProperty("往来类型编码")
  private String contactDetailInfoCode;
  
  /**
   * 往来类型名称
   */
  @ApiModelProperty("往来类型名称")
  private String contactDetailInfoName;
  
  /**
   * 委托划扣银行账号
   */
  @ApiModelProperty("委托划扣银行账号")
  private String delegationBankCode;
  
  /**
   * 关联交易类型编码
   */
  @ApiModelProperty("关联交易类型编码")
  private String relativeTypeCode;
  
  /**
   * 关联交易类型名称
   */
  @ApiModelProperty("关联交易类型名称")
  private String relativeTypeName;
  
  /**
   * 发票稽核	非必须	当为1时，该集成单据稽核且稽核结果为“稽核通过”； 当为0时，该集成单据稽核且稽核结果为“稽核不通过”
   */
  @ApiModelProperty("发票稽核\t非必须\t当为1时，该集成单据稽核且稽核结果为“稽核通过”； 当为0时，该集成单据稽核且稽核结果为“稽核不通过”")
  private Byte invoiceCheck;
  
  /**
   * 是否反记账	可选	1：是
   */
  @ApiModelProperty("是否反记账\t可选\t1：是")
  private Byte isOppositeLedger;
  
  /**
   * 是否一单清 非必须	1为一单清 0和空为非一单清
   */
  @ApiModelProperty("是否一单清 非必须\t1为一单清 0和空为非一单清")
  private Byte singleClearFlag;
  
  /**
   * 单据是否需要后续补充材料归档	 0否1是2事后补票 ,不送默认为否
   */
  @ApiModelProperty("单据是否需要后续补充材料归档\t 0否1是2事后补票 ,不送默认为否")
  private Byte isArchive;
  
  /**
   * 选项：-4-等待生成报账单中;-3-报账单发起失败；-1-报账单删除，－2-退单；2-生成报账单成功；3-已生成SAP凭证
   */
  @ApiModelProperty("选项：-4-等待生成报账单中;-3-报账单发起失败；-1-报账单删除，－2-退单；2-生成报账单成功；3-已生成SAP凭证")
  private Byte status;
  
  /**
   * SAP凭证号
   */
  @ApiModelProperty("SAP凭证号")
  private String sapCertificateCode;
  
  /**
   * 凭证年度
   */
  @ApiModelProperty("凭证年度")
  private String year;
  
  /**
   * 制证人账号	非必须	状态已生成SAP凭证时为必须，可在清账时作为清账人反馈
   */
  @ApiModelProperty("制证人账号\t非必须\t状态已生成SAP凭证时为必须，可在清账时作为清账人反馈")
  private String sapCreator;
  
  /**
   * 非必须	-3状态对应的发起失败信息
   */
  @ApiModelProperty("非必须\t-3状态对应的发起失败信息")
  private String abstract_;
  
  /**
   * 核定金额	必填	主单核定金额 20190213
   */
  @ApiModelProperty("核定金额\t必填\t主单核定金额 20190213")
  private BigDecimal auditSum;
  
  /**
   *
   */
  private String actName;
  
  /**
   *
   */
  private String handlerAccount;
  /**
   * 报账日期
   */

  @TableField(typeHandler = FastjsonTypeHandler.class)
  private JSONObject json;

  @ApiModelProperty("XML报文")
  private String xml;

  @ApiModelProperty("XML报文中的核心内容")
  private String mainXml;

  @TableField(fill = FieldFill.INSERT)
  @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
  private Date createTime;



  @ApiModelProperty("是否已经发送短信，发送为true，未发送为false")
  private Boolean isSendShortMessage;

  @ApiModelProperty("相关票据是否回传或撤销")
  private Boolean isCancelOrFeedback;

  @TableField(exist = false)
  private static final long serialVersionUID = 1L;
  
  public String getAbstract() {
    return abstract_;
  }
  
  public void setAbstract(String abstract_) {
    this.abstract_ = abstract_;
  }
  
  public TWiteoffInstance(WiteoffData jobDTO, String xml, JSONObject json) {
    this.xml = xml;
    this.json = json;
    BeanUtils.copyProperties(jobDTO, this);
    this.desc_ = jobDTO.getDesc();
    this.status = -4;
    this.auditSum = jobDTO.getSum();
    this.otherSystemMainId = jobDTO.getOtherSystemMainId();
    this.isSendShortMessage = false;
  }
  
  public TWiteoffInstance(WiteoffBase jobDTO, String xml, String mainXml, JSONObject json) {
    this.xml = xml;
    this.mainXml = mainXml;
    this.json = json;
    this.systemCode = "passbook";
    BeanUtils.copyProperties(jobDTO, this);
    this.desc_ = jobDTO.getDesc();
    if(jobDTO.getIsAgain())
    {
      this.status=jobDTO.getIsNeedAudit() ? (byte) -6 : -4;
    }
    else
    {
      this.status = jobDTO.getIsNeedAudit() ? (byte) -5 : -4;
    }
    this.auditSum = jobDTO.getSum();
    this.otherSystemMainId = jobDTO.getOtherSystemMainId();
    this.isSendShortMessage=false;
  }
}